package cn.iocoder.yudao.module.reading.service.punch;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchCalendarRespVO;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchCreateReqVO;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchRecordRespVO;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.UserStatsRespVO;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchUpdateReqVO;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.PunchCalendarAllRespVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.punch.PunchRecordDO;

import java.time.LocalDate;
import java.util.List;

/**
 * 学习打卡 Service 接口
 *
 * @author 李晨
 */
public interface PunchService {

    /**
     * 创建学习打卡
     *
     * @param userId      用户ID
     * @param createReqVO 创建信息
     * @return 打卡记录ID
     */
    Long createPunch(Long userId, PunchCreateReqVO createReqVO);

    /**
     * 获得打卡记录
     *
     * @param id 编号
     * @return 打卡记录
     */
    PunchRecordDO getPunchRecord(Long id);

    /**
     * 获得用户打卡记录列表
     *
     * @param userId 用户ID
     * @param limit  限制数量
     * @return 打卡记录列表
     */
    List<PunchRecordRespVO> getPunchRecords(Long userId, Integer limit);

    /**
     * 分页获得用户打卡记录列表
     *
     * @param userId    用户ID
     * @param pageParam 分页参数
     * @return 分页结果
     */
    PageResult<PunchRecordRespVO> getPunchRecordsPage(Long userId, PageParam pageParam);

    /**
     * 获得打卡日历
     *
     * @param userId    用户ID
     * @param yearMonth 年月，格式：2024-01
     * @return 打卡日历
     */
    PunchCalendarRespVO getPunchCalendar(Long userId, String yearMonth);

    /**
     * 检查今日是否可以打卡
     *
     * @param userId 用户ID
     * @return 是否可以打卡
     */
    boolean canPunchToday(Long userId);

    /**
     * 获得今日打卡记录
     *
     * @param userId 用户ID
     * @return 今日打卡记录，如果未打卡则返回null
     */
    PunchRecordRespVO getTodayPunch(Long userId);

    /**
     * 获得打卡详情
     *
     * @param userId  用户ID
     * @param punchId 打卡记录ID
     * @return 打卡详情
     */
    PunchRecordRespVO getPunchDetail(Long userId, Long punchId);

    /**
     * 删除打卡记录
     *
     * @param userId  用户ID
     * @param punchId 打卡记录ID
     */
    void deletePunch(Long userId, Long punchId);

    /**
     * 更新用户统计数据
     *
     * @param userId 用户ID
     */
    void updateUserStats(Long userId);

    /**
     * 获取用户阅读统计
     *
     * @param userId 用户ID
     * @return 用户阅读统计
     */
    UserStatsRespVO getUserStats(Long userId);

    /**
     * 获取完整打卡日历
     *
     * @param userId 用户ID
     * @return 完整打卡日历
     */
    PunchCalendarAllRespVO getPunchCalendarAll(Long userId);

    /**
     * 更新打卡记录
     *
     * @param userId      用户ID
     * @param punchId     打卡记录ID
     * @param updateReqVO 更新请求
     */
    void updatePunch(Long userId, Long punchId, PunchUpdateReqVO updateReqVO);

    /**
     * 获取公开打卡动态列表
     *
     * @param currentUserId 当前用户ID，用于判断关注状态
     * @param limit         限制数量
     * @return 公开打卡动态列表
     */
    List<PunchRecordRespVO> getPublicPunchRecords(Long currentUserId, Integer limit);

    /**
     * 分页获取公开打卡动态列表
     *
     * @param currentUserId 当前用户ID，用于判断关注状态
     * @param pageParam     分页参数
     * @return 分页结果
     */
    PageResult<PunchRecordRespVO> getPublicPunchRecordsPage(Long currentUserId, PageParam pageParam);

    /**
     * 根据班级ID获取打卡记录
     *
     * @param classId 班级ID
     * @return 打卡记录列表
     */
    List<PunchRecordRespVO> getPunchRecordsByClassId(Long classId);

    /**
     * 根据班级ID和日期范围获取打卡记录
     *
     * @param classId   班级ID
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 打卡记录列表
     */
    List<PunchRecordRespVO> getPunchRecordsByClassIdAndDateRange(Long classId, LocalDate startDate, LocalDate endDate);

    /**
     * 统计班级打卡记录总数
     *
     * @param classId 班级ID
     * @return 打卡记录总数
     */
    Long countPunchRecordsByClassId(Long classId);

}
